package cn.edu.swu.miniwebsvr.core;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.StringTokenizer;
import java.util.function.BiConsumer;
import java.util.regex.Pattern;

public class HttpParser {

    private static final Pattern REQUEST_LINE_PATTERN = Pattern.compile("^([A-Z]+) (\\S+) (HTTP/\\d+\\.\\d+)$");

    public static Parameter parse(InputStream inputStream) throws IOException {
        Parameter parameter = new Parameter();
        StringBuilder lineBuffer = new StringBuilder();

        // TODO: [222024321072057/王文薏]
        // 1. 读取并解析 HTTP 请求行 (e.g., GET /path?param=value HTTP/1.1)
        //    - 设置 parameter.setMethod()
        //    - 设置 parameter.setUrl()，并解析出 URL 参数 (e.g., ?param=value)，存入 parameter.urlParams
        // 2. 循环读取并解析所有 HTTP 请求头 (e.g., Host: localhost:8080)
        //    - 存入 parameter.headers
        // 3. 根据请求方法 (Method) 和请求头 (Content-Length, Content-Type) 判断并读取请求体
        //    - 适用于 POST 请求，解析请求体中的参数，存入 parameter.bodyParams
        BufferedReader reader = new BufferedReader(
                new InputStreamReader(inputStream, StandardCharsets.UTF_8)
        );
        String requestLine = reader.readLine();
        if (requestLine == null || requestLine.isEmpty()) {
            throw new IOException("Invalid request line");
        }
        parseRequestLine(requestLine, parameter);

        String headerLine;
        while ((headerLine = reader.readLine()) != null && !headerLine.isEmpty()) {
            parseHeaderLine(headerLine, parameter);
        }

        if ("POST".equalsIgnoreCase(parameter.getMethod())) {
            parseRequestBody(reader, parameter);
        }

        return parameter;
    }

    // 解析请求行，提取方法、URL和协议版本
    private static void parseRequestLine(String requestLine, Parameter parameter) throws IOException {
        StringTokenizer tokenizer = new StringTokenizer(requestLine);
        if (tokenizer.countTokens() < 3) {
            throw new IOException("请求行格式错误: " + requestLine);
        }

        // 提取请求方法 (GET/POST)
        String method = tokenizer.nextToken();
        parameter.setMethod(method);

        // 提取URL及参数
        String urlWithParams = tokenizer.nextToken();
        int queryIndex = urlWithParams.indexOf('?');
        if (queryIndex != -1) {
            // 提取URL路径（不含参数部分）
            String url = urlWithParams.substring(0, queryIndex);
            parameter.setUrl(url);

            // 解析URL参数（?后面的部分）
            String queryParams = urlWithParams.substring(queryIndex + 1);
            parseUrlEncodedParams(queryParams, (BiConsumer<String, String>) parameter.getUrlParams());
        } else {
            // 无参数的URL
            parameter.setUrl(urlWithParams);
        }
    }

    // 解析请求头，存入headers集合
    private static void parseHeaderLine(String headerLine, Parameter parameter) {
        int colonIndex = headerLine.indexOf(':');
        if (colonIndex != -1) {
            String key = headerLine.substring(0, colonIndex).trim();
            String value = headerLine.substring(colonIndex + 1).trim();
            parameter.getHeaders().put(key, value);  // 调用Parameter的addHeader方法
        }
    }

    // 解析请求体（POST方法）
    private static void parseRequestBody(BufferedReader reader, Parameter parameter) throws IOException {
        // 从请求头获取内容长度
        String contentLengthStr = parameter.getHeader("Content-Length");
        if (contentLengthStr == null || contentLengthStr.isEmpty()) {
            return; // 无请求体内容
        }

        int contentLength;
        try {
            contentLength = Integer.parseInt(contentLengthStr);
        } catch (NumberFormatException e) {
            throw new IOException("无效的Content-Length值：" + contentLengthStr);
        }
        // 读取请求体内容
        char[] bodyChars = new char[contentLength];
        int bytesRead = reader.read(bodyChars, 0, contentLength);
        if (bytesRead != contentLength) {
            throw new IOException("请求体长度与Content-Length不符");
        }
        String body = new String(bodyChars, 0, bytesRead);

        // 解析表单类型的请求体（application/x-www-form-urlencoded）
        String contentType = parameter.getHeaders().get("Content-Type");
        if (contentType != null && contentType.contains("application/x-www-form-urlencoded")) {
            parseUrlEncodedParams(body, (BiConsumer<String, String>) parameter.getBodyParams());
        }
    }

    /**
     * 通用解析方法：解析URL编码的参数字符串（如name=张三&age=20）
     * @param paramString 参数字符串
     * @param paramConsumer 用于存储参数的函数（区分URL参数和Body参数）
     */
    private static void parseUrlEncodedParams(String paramString,
                                              java.util.function.BiConsumer<String, String> paramConsumer) throws IOException {
        String[] paramPairs = paramString.split("&");
        for (String pair : paramPairs) {
            if (pair.isEmpty()) continue;

            String[] keyValue = pair.split("=", 2); // 最多分割为两部分（处理没有值的参数）
            String key = URLDecoder.decode(keyValue[0], StandardCharsets.UTF_8.name());
            String value = keyValue.length > 1
                    ? URLDecoder.decode(keyValue[1], StandardCharsets.UTF_8.name())
                    : "";

            paramConsumer.accept(key, value);
        }
    }

    // TODO: [222024321072057/王文薏] 可以添加辅助方法来简化字符串解析和 URL 解码
    // URL解码辅助方法（处理特殊字符和中文）
    private static String decodeUrl(String encoded) {
        try {
            return URLDecoder.decode(encoded, StandardCharsets.UTF_8.name());
        } catch (Exception e) {
            return encoded; // 解码失败时返回原始字符串
        }
    }
}
